/*
 * main.c
 *
 *  Created on: 30.03.2014
 *      Author: alexs
 */
//i2c 24lc64
//SPI SST25VF512

#include "main.h"
#include "usart.h"
#include "i2c_eeprom.h"
#include "rfid.h"
#include <string.h>

void hw_init(void) __attribute__ ((naked)) __attribute__ ((section (".init7")));
void hw_init() {
	/*таймер 100 */
	ICR1=781;
	/*
	TCCR1B=(1<<WGM12)|(1<<WGM13)|(1<<CS12)|(1<<CS10);
	TIFR1=0xff;
	 */
	DDRD|=(1<<PD5)|(1<<PD6);
	PORTD|=(1<<PD5)|(1<<PD6);

	/*USART 38400,8,n,1*/
	/*	Его уже настроил бутлоадер!!!*/
	/*
	UCSR0A=(1<<U2X0);
	UCSR0B=(1<<RXEN0)|(1<<TXEN0);
	UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
	UBRR0=F_CPU / (8L * USARTBAUD) -1;
	 */

	/*	ADC - будем мерить батарейку*/
	/*	res 1023 по расчетам тревога при 902 и при 810 кирдык*/
	/*	res 255 по расчетам тревога при 225 и при 202 кирдык*/
	/*	на диоде падает 0,26*/
	ADMUX=(1<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(0<<MUX0);
	ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0);
	ADCSRB=0;
}
uint8_t ReadClassic(uint8_t *);

int main () {
	uint8_t i;
	ultralight_t Token,tmp,Local;
	uint16_t addr;
	tag_stat status;
	ultralight_page01_t Page01;
	uint16_t CType=0;
	uint8_t SN_len=0;
	uint8_t cnt10=0;
	uint8_t Vcc;
	uint8_t Valid=0;
	uint8_t Found=0;
	uint8_t Report_ok=0;

	InitRc522();
	Local.cnt=0;

/*
#ifdef DEBUG
	if ((PIND&(1<<PD0))&&(!Report_ok)) {
		for (addr=0;addr<EE_TOP;addr+=10){
			i2c_ee_read_tag(addr,(uint8_t *)&tmp);
			if (tmp.cnt==0) break;
			//			prn_int(tmp.cnt);
			put_str(">> ");
			for (i=0;i<10;i++) prn_hex(tmp.buff[i]);
			put_str("\n");
		}
	}
#endif
*/

	for (;;) {

		if ((TIFR1&0x07)>0) {
			TIFR1=0xff; //Сброс флага таймера

			//Чтение ADC и запуск нового измерения.
			while (!(ADCSRA&(1<<ADIF)));
			Vcc = ADCH;
			ADCSRA|=(1<<ADSC)|(1<<ADIF);

			//Выполняем если ID внутренней метки совпал с ID в памяти.
			if (Valid) {
				if ((PIND&(1<<PD0))&&(!Report_ok)) {
					put_str("***** ");
					for (i=0;i<7;i++) prn_hex(Local.sn[i]);
					put_str(" *****\n");
					for (addr=10;addr<EE_TOP;addr+=10){
						i2c_ee_read_tag(addr,(uint8_t *)&tmp);
						if (tmp.cnt==0) break;
						prn_int(tmp.cnt);
						put_str("|");
						for (i=0;i<7;i++) prn_hex(tmp.sn[i]);
						put_str("\n");
					}
					put_str("***** ");
					for (i=0;i<7;i++) prn_hex(Local.sn[i]);
					put_str(" *****\n\n");

					Report_ok=1;
				}


				if (Vcc<202) {
					PIND|=(1<<PD5);
				}else if (Vcc<225) {
					if ((cnt10 = cnt10 % 10)) {PIND|=(1<<PD5);}
				}else{
					PORTD&=~(1<<PD5);
				}
			}
		}

		if (Found) continue;
		status= find_tag(&CType);
		if (status==TAG_NOTAG) {
			continue;
		}else if ((status!=TAG_OK)&&(status!=TAG_COLLISION)) {continue;}
		if (select_tag_sn(Token.sn,&SN_len)!=TAG_OK) {continue;}

		//Первая метка - она локальная?
		if (Local.cnt==0) {
#ifdef DEBUG
			put_str("Check\n");
#endif
			PcdHalt();

#ifdef CLEAR_ALL
			Token.cnt=0xffff;
			i2c_ee_clear_tags((uint8_t *)&Token);
#endif
			if (i2c_ee_read_tag(0,(uint8_t *)&tmp)) {
				if (memcmp(&Token.sn[0],&tmp.sn[0],7)==0) {
					memcpy(&Local,&Token,sizeof(Local));
					Local.cnt=0xffff;
					Valid=1;
#ifdef DEBUG
					put_str("Valid\n");
#endif
					continue;
				}
			}
			continue;
		}


		// Вторая Метка
#ifdef DEBUG
		put_str("\nType: ");
		prn_hex(CType);
		put_str("\nLength: ");
		prn_hex(SN_len);
		put_str("\nSN: ");
		for (i=0;i<SN_len;i++) 	prn_hex(Token.sn[i]);
		put_str("\n\n");
#endif

		if (SN_len!=7) { /* Если метка classic */
			if (ReadClassic(Token.sn)) {
				i2c_ee_clear_tags((uint8_t *)&Local);
			}
			continue; //TODO 4k
		}

		/*Цикл поиска метки в памяти. Если найдена, то found=1 */
		for (addr=10;addr<EE_TOP;addr+=10){
			i2c_ee_read_tag(addr,(uint8_t *)&tmp);
			if (tmp.cnt==0) break;
			if (memcmp(&tmp.sn[0],&Token.sn[0],7)==0) {
				Found=1;
				break;
			}
		}

		if (!Found) { /* Метка новая */
			if (read_tag_str(COUNT_PAGE,Page01.buff,4)!=0) {
#ifdef DEBUG
				put_str("ERROR1\n");
#endif
				PcdHalt();
				continue;
			}
#ifdef DEBUG
			put_str("Count: ");
			prn_int(Page01.cnt1);
			put_str(" : ");
			prn_int(Page01.cnt2);
			put_str("\n");
#endif
			/*Если в 8 блоке бред, то обнулим его*/
			if (Page01.cnt1!=(~Page01.cnt2)) {
				Page01.cnt1=0;
			}
			/*Увеличим счетчик посетителей и запишем его*/
			Page01.cnt1++;
			Page01.cnt2=~Page01.cnt1;
			Token.cnt=Page01.cnt1;
			write_tag_str4(COUNT_PAGE,Page01.buff);

			/*Проверим результат записи*/
			if (read_tag_str(COUNT_PAGE,Page01.buff,4)!=0) {
#ifdef DEBUG
				put_str("ERROR2\n");
#endif
				PcdHalt();
				continue;
			}
			if ((Page01.cnt1!=Token.cnt)||(Page01.cnt2!=(~Token.cnt))) {
#ifdef DEBUG
				put_str("ERROR3\n");
#endif
				PcdHalt();
				continue;
			}

			/*Если запись на метку удачна, то сохраним ее в памяти*/
			i2c_ee_write_tag(addr,(uint8_t *)&Token,TAG_LEN);
#ifdef DEBUG
			put_str("Write: ");
			prn_int(addr);
			put_str("\n");
#endif
			Found=1; /*Больше искать меток не будем */
		}else{
#ifdef DEBUG
			put_str("Found: ");
			prn_int(addr);
			put_str("\n");
#endif
		}
		PORTD&=~(1<<PD6);
		PcdHalt();
	}
	return 0;
}

uint8_t ReadClassic(uint8_t * SN) {
	uint8_t SNF[7];
	uint8_t SN_len;
	uint8_t Ctype;
#include "clear.txt"


}
